#pragma once
#include "base/function.h"
#include "util/noncopyable.h"

#include <sys/epoll.h>
namespace net_tools
{
  class Eventloop;
  namespace base
  {
    class Epoll;
    class Timeevent;
    class Channel : util::noncopyable
    {
      friend class Epoll;
      friend class Channelpool;

    public:
      Channel(Epoll *epoll);
      ~Channel();
      void Callback(int epoll_type);
      void Set_read_callback(func cb) { read_callback_ = std::move(cb); };
      void Set_write_callback(func cb) { write_callback_ = std::move(cb); };
      void Set_close_callback(func cb) { close_callback_ = std::move(cb); };
      void Enableread()
      {
        epoll_type_ |= (EPOLLIN | EPOLLPRI | EPOLLRDHUP);
        Event_update();
      };
      void Disableread()
      {
        epoll_type_ &= ~(EPOLLIN | EPOLLPRI | EPOLLRDHUP);
        Event_update();
      };
      void Enablewrite()
      {
        epoll_type_ |= (EPOLLOUT);
        Event_update();
      };
      void Disablewrite()
      {
        epoll_type_ &= ~(EPOLLOUT);
        Event_update();
      };
      void Disableall()
      {
        epoll_type_ = 0;
        Event_update();
      };
      void Listenfd_init(int listenfd) { listenfd_ = listenfd; };
      void Enable_ET()
      {
        epoll_type_ |= EPOLLET;
        Event_update();
      };
      void Disable_ET()
      {
        epoll_type_ &= ~EPOLLET;
        Event_update();
      };
      int Get_listenfd() const { return listenfd_; };
      void Add_to_epoll();
      void Mod_to_epoll();
      void Del_to_epoll();

    private:
      void Event_update() { event_.events = epoll_type_; };
      int listenfd_;
      int epoll_type_;
      func read_callback_;
      func write_callback_;
      func close_callback_;
      epoll_event event_;
      Epoll *epoll_;
    };

  } // namespace base
} // namespace net_tools